#include "StepByStep.h"

Bool EqualParameterOfTwoPCs(PredKnowledge *PC1, TypedList *APara, PredKnowledge *PC2)
{
  TypedList *Para, *Para1, *Para2;
  int        i, Idx1, Idx2, Num;

  Num = NumParaOfPred(PC1->PredNo);
  Para1 = PC1->Para;
  Para2 = PC2->Para;
  for (i = 0; i < Num; i++,Para1++,Para2++) {
    Idx1 = Para1->VList.ParaIdx;
    Idx2 = Para2->VList.ParaIdx;
    if (IsConstant(Idx1) || IsConstant(Idx2)) {
       if (Idx1 != Idx2) break;
    }
    else {
           Para = APara + Idx1;
           if (Para->VList.ParaIdx!=Para2->VList.ParaIdx ||
               !IsSame(Para1->Type->Name, Para2->Type->Name))
              break;
    }
  }

  return (i >= Num);
}

void SortCPCOfActionTree(PKTree *Pk)
{
  PredKnowledge *PC, *PC1, *PC2, *PC3, *PC4, *PC5, *CPC, *Pd;
  ActKnowledge  *ActK;

  Pd = Pk->Pred;

  if (Pd->CPC == NULL) return;

  ActK = Pd->Act;

  CPC = PC1 = NULL;
  PC = ActK->PC;
  while (PC != NULL) {
    PC4 = NULL;
    for (PC3 = Pd->CPC; PC3 != NULL; PC4=PC3,PC3=PC3->next)
      if (PC->PredNo == PC3->PredNo &&
          EqualParameterOfTwoPCs(PC, ActK->Para, PC3)) break;

    PC5 = PC->next;

    if (PC3 == NULL) PC1 = PC;
    else {
           if (PC1 == NULL) ActK->PC = PC5;
           else PC1->next = PC5;

           FreeTypedArray(NumParaOfPred(PC->PredNo), PC->Para);
           free(PC);

           if (PC4 == NULL) Pd->CPC = PC3->next;
           else PC4->next = PC3->next;

           if (CPC == NULL) CPC = PC3;
           else PC2->next = PC3;

           PC2 = PC3;
    }

    PC = PC5;
  }

  PC2->next = NULL;  Pd->CPC = CPC;

  for (ActK = ActK->next; ActK != NULL; ActK = ActK->next) {
    PC1 = NULL;
    for (PC = ActK->PC; PC != NULL; PC = PC4) {
      for (PC3 = Pd->CPC; PC3 != NULL; PC3 = PC3->next)
        if (PC->PredNo == PC3->PredNo &&
            EqualParameterOfTwoPCs(PC, ActK->Para, PC3)) break;

      PC4 = PC->next;

      if (PC3 == NULL) PC1 = PC;
      else {
             if (PC1 == NULL) ActK->PC = PC4;
             else PC1->next = PC4;

             FreeTypedArray(NumParaOfPred(PC->PredNo), PC->Para);
             free(PC);
      }
    }

    if (PC1 != NULL) PC1->next = NULL;
  }
}

void ModifyTreeOfAction()
{
  PredKnowledge *Pd;
  PKTree *Pk, *Pk1, *Pk2;
  int     i;

//PrintKnowledgeTree();
  Pk1 = PK;   Pk2 = nPK;
  for (i = 0; i < NumPred; i++,Pk1++,Pk2++) {
    for (Pk = Pk1->next; Pk != NULL; Pk = Pk->next) {
      Pd = Pk->Pred;
      if (Typing && Pd->NumAct > 1) SortCPCOfActionTree(Pk);
      else {
             FreePCList(Pd->CPC);
             Pd->CPC = NULL;
      }

      FreeEffectList(Pd->CEffect);
      Pd->CEffect = NULL;
    }

    for (Pk = Pk2->next; Pk != NULL; Pk = Pk->next) {
      Pd = Pk->Pred;
      if (Typing && Pd->NumAct > 1) SortCPCOfActionTree(Pk);
      else {
             FreePCList(Pd->CPC);
             Pd->CPC = NULL;
      }

      FreeEffectList(Pd->CEffect);
      Pd->CEffect = NULL;
    }
  }
//PrintKnowledgeTree();
}
